package com.dlg.user.restful.api.controller;

import com.alibaba.dubbo.config.annotation.Reference;
import com.dlg.commons.enums.UserType;
import com.dlg.commons.util.Utils;
import com.dlg.commons.util.codec.Base64;
import com.dlg.commons.viewmodel.ResponseViewModel;
import com.dlg.user.dao.redis.CacheService;
import com.dlg.user.domain.system.OjDictionary;
import com.dlg.user.restful.api.vo.RegisterResponseVo;
import com.dlg.user.rpc.api.system.IDictionaryRpcService;
import com.dlg.user.rpc.api.user.IUserRpcService;
import com.dlg.user.rpc.api.vo.user.*;
import org.apache.commons.lang3.StringUtils;
import org.apache.shiro.authc.credential.PasswordMatcher;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;

import java.io.UnsupportedEncodingException;
import java.math.BigInteger;
import java.net.URLDecoder;

/**
 * Created by zhangjinxia on 2017/8/8.
 */
@RestController
@RequestMapping("/")
public class UserController {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    @Reference
    private IUserRpcService userRpcService;

    @Autowired
    CacheService cacheService;

    @Reference
    private IDictionaryRpcService dictionaryRpcService;

    @Autowired
    PasswordMatcher credentialsMatcher;

    @RequestMapping("/test")
    @ResponseBody
    public String test(){
//        User user = new User();
//        user.setUserName("dlg zjx");

//        List<OjDictionary> dictionaries = dictionaryRpcService.findByGroupCode("jd.scope", (short) 1);


//        UserRegisterRpcVo userRegisterRpcVo = new UserRegisterRpcVo();
//        userRegisterRpcVo.setPassword("666");
//        cacheService.putObject("11",userRegisterRpcVo);
//        List<OjDictionary> dictionaries = dictionaryRpcService.findByGroupCode("jd.scope", (short) 1);

//        return null;
//        return Utils.id().toString()+"---"+Utils.id().toString();

//        UserRegisterRpcVo userRegisterRpcVo = new UserRegisterRpcVo();
//        userRegisterRpcVo.setPassword("666");
        //保存用户,先放到redis，再通过mq持久化
//        String registerVoJson = JSON.toJSONString(userRegisterRpcVo);
//        cacheService.putObjectPermanent("777", userRegisterRpcVo);
//
//
//        String json = (String) redisCacheService.getObject("777");
//        JSONObject object = JSON.parseObject(json);
//        return object.getString("password");

//        UserRegisterRpcVo userRegisterRpcVo = new UserRegisterRpcVo();
//        userRegisterRpcVo.setOpenId("6789");
//        mqSender.send(MqKeyConstants.register, userRegisterRpcVo);
//        return Utils.encryptPassword("111111", credentialsMatcher.getPasswordService());
//        return Utils.matchPassword("111111","$shiro1$SHA-256$500000$NRWUmo0Pueeod2z4i/m0QA==$UZtMt4K3XbjWc1cSkyk62w+cshnZKzzfh/Fm/4Nae3E=", credentialsMatcher.getPasswordService());
        return null;
    }

    /**
     * 注册时设置对象的属性
     * @param userRegisterRpcVo
     * @param userType
     * @param personalUserAttributeRpcVo
     * @param enterpriseUserAttributeRpcVo
     * @return
     * @throws UnsupportedEncodingException
     */
    private UserType setProperties(UserRegisterRpcVo userRegisterRpcVo, String userType,
                               PersonalUserAttributeRpcVo personalUserAttributeRpcVo,
                               EnterpriseUserAttributeRpcVo enterpriseUserAttributeRpcVo,
                               String openId) throws UnsupportedEncodingException {

        // add by xpp ,解决代理商邀请用户注册时，邀请页面传过来的企业名称和联系人乱码  begin
        if (null != userRegisterRpcVo.getUsername()) {
            userRegisterRpcVo.setUsername(URLDecoder.decode(userRegisterRpcVo.getUsername(), "utf-8"));
        }
        if (null != personalUserAttributeRpcVo.getName()) {
            personalUserAttributeRpcVo.setName(URLDecoder.decode(personalUserAttributeRpcVo.getName(), "utf-8"));
        }
        if (null != enterpriseUserAttributeRpcVo.getName()) {
            enterpriseUserAttributeRpcVo.setName(URLDecoder.decode(enterpriseUserAttributeRpcVo.getName(), "utf-8"));
        }
        // add by xpp ,解决代理商邀请用户注册时，邀请页面传过来的企业名称和联系人乱码  end

        //设置类型
        UserType type = UserType.getTypeByStr(userType);
        userRegisterRpcVo.setType(type);
        //设置origin
        String origin = "source:" + userRegisterRpcVo.getSource() + ",client:" + userRegisterRpcVo.getClient()
                + ",appVersion:" + userRegisterRpcVo.getAppVersion();
        if (null != userRegisterRpcVo.getActivity()) {
            origin += ",activity:" + userRegisterRpcVo.getActivity();
        }
        if (null != userRegisterRpcVo.getChannel()) {
            origin += ",channel:" + userRegisterRpcVo.getChannel();
        }
        if (null != userRegisterRpcVo.getWs()) {
            origin += ",ws:" + userRegisterRpcVo.getWs();
        }
        userRegisterRpcVo.setOrigin(origin);


        //设置个人用户的角色
        Short role = personalUserAttributeRpcVo.getRole();
        if (Short.valueOf("2").equals(role)) {
            personalUserAttributeRpcVo.setRole(Short.valueOf("1"));
        }
        if (Short.valueOf("1").equals(role)) {
            personalUserAttributeRpcVo.setRole(Short.valueOf("2"));
        }
        if (null != openId && !"".equals(openId) && userRegisterRpcVo.getIsLogin() == com.dlg.commons.constant.DigitConstant.SHORT_ONE) {
            userRegisterRpcVo.setOpenId(Base64.getFromBase64(openId).substring(1));
        }
        //设置个人用户和企业用户

        userRegisterRpcVo.setPersonalUserRpcVo(personalUserAttributeRpcVo);
        userRegisterRpcVo.setEnterpriseUserRpcVo(enterpriseUserAttributeRpcVo);
        return type;
    }

    @RequestMapping(value = "/register")
    @ResponseBody
    public ResponseViewModel<RegisterResponseVo> register(UserRegisterRpcVo userRegisterRpcVo, String userType, String openId,
                                      PersonalUserAttributeRpcVo personalUserAttributeRpcVo,
                                      EnterpriseUserAttributeRpcVo enterpriseUserAttributeRpcVo) {
        ResponseViewModel<RegisterResponseVo> result = new ResponseViewModel<>();
        RegisterResponseVo registerResponseVo = new RegisterResponseVo();
        BigInteger id = BigInteger.ZERO;
        try {
            UserType type = "1".equals(userType) ? UserType.PERSONAL : "2".equals(userType) ? UserType.ENTERPRISE : null;
            userRegisterRpcVo.setType(type);
            //校验参数是否合法
            String errorMsg = userRegisterRpcVo.validateRegister();
            if (org.apache.commons.lang3.StringUtils.isNoneEmpty(errorMsg)){
                return ResponseViewModel.error(errorMsg);
            }
            //设置属性
            setProperties(userRegisterRpcVo, userType, personalUserAttributeRpcVo, enterpriseUserAttributeRpcVo, openId);
            //设置密码
            userRegisterRpcVo.setPassword(Utils.encryptPassword(userRegisterRpcVo.getPassword().trim(), credentialsMatcher.getPasswordService()));

            id = userRpcService.register(userRegisterRpcVo, userType);
        } catch (Exception e) {
            logger.error("注册失败",e);
            return ResponseViewModel.error("注册失败：" + Utils.getDubboExceptionMesaage(e));
        }
        registerResponseVo.setId(id);
        result.setData(registerResponseVo);
        return result;
    }

    /**
     * 查询用户详情
     * @author lhh@gongren.com
     * @since 2017年3月30日 上午9:34:05
     * @param phone
     * @param userType
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/api/userRest/queryUserDetail", method = RequestMethod.POST)
    public ResponseViewModel<UserRpcVo> queryUserDetail(String phone,String userType) {
        ResponseViewModel<UserRpcVo> result = new ResponseViewModel<>();
        UserRpcVo userRpcVo;
        if(StringUtils.isEmpty(phone) || StringUtils.isEmpty(userType)){
            return result;
        }
        try {
            userRpcVo = userRpcService.queryUserDetail(phone, UserType.getTypeByStr(userType));
            if (userRpcVo != null) {
                String distance;
                if (userRpcVo.getType().equals(UserType.PERSONAL)){
                    PersonalUserAttributeRpcVo personalUserAttributeRpcVo = userRpcVo.getPersonalUserAttributeRpcVo();
                    distance = personalUserAttributeRpcVo==null ? null : personalUserAttributeRpcVo.getDistance();
                }else{
                    EnterpriseUserAttributeRpcVo enterpriseUserAttributeRpcVo = userRpcVo.getEnterpriseUserAttributeRpcVo();
                    distance = enterpriseUserAttributeRpcVo==null ? null : enterpriseUserAttributeRpcVo.getDistance();
                }
                try {
                    OjDictionary dictionary = dictionaryRpcService.findByDataCode(distance);
                    userRpcVo.setDistance(dictionary==null ? null : dictionary.getDataValue());
                } catch (Exception e) {
                    logger.error("获取对应的接单范围失败:{}", e);
                }

                Integer count = userRpcService.getJobCountByUserId(userRpcVo.getId());
                userRpcVo.setServiceCount(count);

                // 查询是否显示诚信档案标识
                OjDictionary dictionary = dictionaryRpcService.findByDataCode("is_show_credit_archive");
                if (dictionary != null && dictionary.getDataValue() != null) {
                    userRpcVo.setIsShowCreditArchive(dictionary.getDataValue());
                }
            }
        } catch (Exception e) {
            logger.error("查询用户详情出错", e);
            return ResponseViewModel.error("查询用户详情失败:" + Utils.getDubboExceptionMesaage(e));
        }
        result.setData(userRpcVo);
        return result;
    }


    /**
     * 添加代理商用户详情
     * @param enterpriseAgentAttributeRpcVo
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/api/userRest/addEnterpriseAgent", method = RequestMethod.POST)
    public ResponseViewModel<BigInteger> addEnterpriseAgent(EnterpriseAgentAttributeRpcVo enterpriseAgentAttributeRpcVo, String phone, String userType) {
        ResponseViewModel<BigInteger> result = new ResponseViewModel<>();
        try {
            userRpcService.addEnterpriseAgent(enterpriseAgentAttributeRpcVo, phone, userType);
        } catch (Exception e) {
            logger.error("保存用户代理商出错", e);
            return ResponseViewModel.error("保存用户代理商信息失败:" + Utils.getDubboExceptionMesaage(e));
        }
        return result;
    }

    /**
     * 更新用户信息
     * @author lhh@gongren.com
     * @since 2017年3月30日 上午9:34:58
     * @param userRpcVo
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/api/userRest/updateUser", method = RequestMethod.POST)
    public ResponseViewModel updateUserById(UserRpcVo userRpcVo, String phone, String userType) {
        ResponseViewModel result = new ResponseViewModel();
        try {
            userRpcService.updateUserById(userRpcVo, phone, userType);
        } catch (Exception e) {
            logger.error("更新用户信息出错", e);
            return ResponseViewModel.error("更新用户信息失败 :" + Utils.getDubboExceptionMesaage(e));
        }
        return result;
    }

    /**
     * 根据用户id更新个人用户信息
     * @author lhh@gongren.com
     * @since 2017年3月30日 上午9:35:06
     * @param attributeRpcVo
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/api/userRest/updatePersonalUser", method = RequestMethod.POST)
    public ResponseViewModel updatePersonalUserByUserId(PersonalUserAttributeRpcVo attributeRpcVo, String phone, String userType) {
        ResponseViewModel result = new ResponseViewModel<>();
        try {
            userRpcService.updatePersonalUserByUserId(attributeRpcVo, phone, userType);
        } catch (Exception e) {
            logger.error("查询个人用户信息出错", e);
            return ResponseViewModel.error("查询个人用户信息失败:" + Utils.getDubboExceptionMesaage(e));
        }
        return result;
    }

    /**
     * 根据用户ID更新企业用户信息
     * @author lhh@gongren.com
     * @since 2017年3月30日 上午9:35:13
     * @param attributeRpcVo
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/api/userRest/updateEnterpriseUser", method = RequestMethod.POST)
    public ResponseViewModel updateEnterpriseUserByUserId(EnterpriseUserAttributeRpcVo attributeRpcVo, String phone, String userType) {
        ResponseViewModel result = new ResponseViewModel<>();
        try {
            userRpcService.updateEnterpriseUserByUserId(attributeRpcVo, phone, userType);
        } catch (Exception e) {
            logger.error("更新企业用户信息出错", e);
            return ResponseViewModel.error("更新企业用户信息失败:" + Utils.getDubboExceptionMesaage(e));
        }
        return result;
    }

    /**
     * 根据ID更新企业代理商信息
     * @author lhh@gongren.com
     * @since 2017年3月30日 上午9:35:13
     * @param attributeRpcVo
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/api/userRest/updateEnterpriseAgent", method = RequestMethod.POST)
    public ResponseViewModel updateEnterpriseAgentByUserId(EnterpriseAgentAttributeRpcVo attributeRpcVo, String phone, String userType) {
        ResponseViewModel result = new ResponseViewModel<>();
        try {
            userRpcService.updateEnterpriseAgentByUserId(attributeRpcVo, phone, userType);
        } catch (Exception e) {
            logger.error("更新企业代理商信息出错", e);
            return ResponseViewModel.error("更新企业代理商信息失败:" + Utils.getDubboExceptionMesaage(e));
        }
        return result;
    }

    /**
     * 修改密碼
     * @param phone
     * @param userType
     * @param newPassword
     * @param oldPassword
     * @return
     */
    @ResponseBody
    @RequestMapping(value = "/api/userRest/updateUserPassword", method = RequestMethod.POST)
    public ResponseViewModel updateUserPassword(String phone, String userType, String newPassword, String oldPassword) {
        ResponseViewModel result = new ResponseViewModel();
        try {
            userRpcService.updateUserPassword(phone,userType,newPassword,oldPassword);
        } catch (Exception e) {
            logger.error("更新用户信息出错", e);
            return ResponseViewModel.error("更新用户信息失败 :" + Utils.getDubboExceptionMesaage(e));
        }
        return result;
    }
}
